using System;
using System.Collections.Generic;
using System.Text;
using LibGreen.Jabber.ProtocolElements;

namespace LibGreen.Jabber.Dispatchers
{
    /// <summary>
    /// Processes and dispatches message stanzas
    /// </summary>
    /// <remarks>With regard to typing notifications:  I'm specifically giving the finger to XEP-0022, jabber:x:event,
    /// as that standard states that it has been superceded by XEP-0085, http://jabber.org/protocol/chatstates.
    /// libpurple sends both types of notifications for typing, but for god's sake...for god's sake.</remarks>
    class MessageDispatcher : IDispatcher
    {
        private readonly Session session;

        /// <summary>
        /// Initializes a new MessageDispatcher
        /// </summary>
        /// <param name="session">The <see cref="Session"/> used by the dispatcher</param>
        public MessageDispatcher(Session session)
        {
            this.session = session;
        }

        #region IDispatcher Members
        /// <summary>
        /// Initializes the dispatcher
        /// </summary>
        public void Initialize()
        {
        }

        /// <summary>
        /// Dispatches a newly received <see cref="Element"/> for processing
        /// </summary>
        /// <param name="element">The newly received <see cref="Element"/> that must be processed</param>
        /// <returns><c>true</c> if the dispatcher processed the element, <c>false</c> otherwise</returns>
        public bool DispatchElement(Element element)
        {
            if (element.Name != "message")
            {
                return false;
            }

            return ProcessMessage(new MessageElement(element));
        }

        #endregion

        /// <summary>
        /// Processes a &lt;message&gt; element
        /// </summary>
        /// <param name="element">An <see cref="MessageElement"/> containing a message stanza</param>
        /// <returns><c>true</c> if the element was processed, <c>false</c> otherwise</returns>
        private bool ProcessMessage(MessageElement element)
        {
            Element body = null, error = null;

            foreach (Element child in element.Children)
            {
                if (child.Name == "body")
                {
                    body = child;
                }
                else if (child.Name == "error")
                {
                    error = child;
                }
            }

            if (body != null)
            {
                session.Messages.OnMessageReceived(element.From, body.Value);
            }

            return true;
        }
    }
}
